import json
import os
import time
import traceback
from datetime import datetime
from os import path
from shutil import copyfile
from typing import List

import requests
from requests_toolbelt import MultipartEncoder
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait

from apps.logger_config import logger
from apps.model import BankSideInfo, HouseApprove, HouseConfirm, BankSideExtendInfo
from apps.seleuinms import CreateDriver
from apps.seleuinms.process.common import request3
from apps.seleuinms.requests.Jisudai import NormalLoan, Shangdaitong
from apps.seleuinms.requests.common import YZYH_REQUEST_URL, get_house_qz, get_business_item
from apps.seleuinms.utils import get_value
from apps.seleuinms.utils.request_utils import get_headers, parse_response
from apps.utils import curtime

"""
 在3.0业务系统中，所有的申请分为三种类型， 从extensionFieldOne.applyType 可以判断
 审批类型 01/额度审批  02/支用审批 03/贷款审批
 01 为经营贷，可以有多个合同，主合同由贷款用途决定
    # findContractList 查找所有的合同
        贷款用途分类 01-消费 02-三农 # 感觉这里是错的。 应该是01为三农 02为消费
        contract.loanUsageCls
            01 消费贷合同：
                contract.contractType 02 个人消费借款合同 是主合同
            02 三农合同：
                contract.contractType 如果有 03 综合授信合同-主合同 否则01为主合同
 02 不存在
 03 一手房类， 单笔审批。 合同通过贷款审批构成
"""

cmd = "tasklist | findstr FdHttpServer.exe"
d = os.popen(cmd)
result = d.read()
if result == '':
    raise Exception(500, '插件系统未启动！')
command = 'wmic process where name="FdHttpServer.exe" get processid,name,executablepath'
d = os.popen(command)
result = d.read()
"""插件执行文件根路径"""
execute_path = result.split('\n')[2].split(' ')[0]
# execute_path = ''

"""产权证书根路径"""
file_basepath = path.abspath(path.join(path.dirname(path.abspath(__file__)), '../../../static/chanquan'))

USERNAME = '20080426100'
PASSWORD = 'WnFxODExMDE4'


def find_main_contract(business_key, cookies):
    """查找主合同"""
    url = 'http://22.230.57.12:8080/creaditContract/findContractList'
    params = {
        'busiNo': business_key,
        'deledFlag': '0',
    }
    contracts = [item for item in get_value(request3(url, params, cookies), 'data.grid') if
                 item.get('contractType') == '01']
    if len(contracts) != 1:
        return None
    return contracts[0]


def select_by_text(col, text):
    col.find_element_by_tag_name('input').click()
    # 等待下拉选项弹出
    time.sleep(3)
    dds = col.find_elements_by_tag_name('dd')
    for dd in dds:
        if dd.text == text and dd.is_enabled():
            dd.click()
            return
    pass


def add_qz(params, task_id, cookies):
    url = 'http://22.230.57.12:8080/warrantInfo/saveWarrantInfo'
    data = {
        'provCode': '3200',  # 省份
        'phyDocTypeArray': None,
        'curDayClassMode': '02',  # 录入方式
        'mrtgEnrollInstType': '02',  # 登记机构类型
        'enrollInstName': '盐城市自然资源和规划局',  # 登记机构名称
        'warrantStatusCode': '01',  # 页面选中状态
        'taskId': task_id,
        '_curMenuCode': None,
    }
    for key in params:
        data[key] = params.get(key)
    return request3(url, data, cookies)


def get_house_info(collat_id, cookies):
    result = {
        'guaranteeBaseInfoApi': '',
        'guaranteeOwnShareInfoApi': '',
        'housePropertyInfoApi': '',
        'insuranceInfoListApi': '',
        'notarizationInfoListApi': '',
    }
    url = 'http://22.230.57.12:8080/guaranteeBaseInfo/getGuaranteeBaseInfo'
    params = {
        'collatId': collat_id,
        'provCode': '3200',
    }
    base_info = request3(url, params, cookies)
    data = base_info.get('data')
    result['guaranteeBaseInfoApi'] = json.dumps({'guaranteeBaseInfo': data}, ensure_ascii=False)
    url = 'http://22.230.57.12:8080/guaranteeOwnShareInfo/queryGuaranteeOwnShareInfoList'
    params = {
        'collatId': collat_id,
        'provCode': '3200',
        'deledFlag': '0'
    }
    share_info_list = request3(url, params, cookies)
    result['guaranteeOwnShareInfoApi'] = json.dumps({'guaranteeOwnShareInfoList': share_info_list.get('data')},
                                                    ensure_ascii=False)

    url = 'http://22.230.57.12:8080/insuranceInfo/queryInsuranceInfoList'
    insurance_list = request3(url, params, cookies)
    result['insuranceInfoListApi'] = json.dumps({'insuranceInfoList': insurance_list.get('data')}, ensure_ascii=False)

    url = 'http://22.230.57.12:8080/notarizationInfo/queryNotarizationInfoList'
    notari_list = request3(url, params, cookies)
    result['notarizationInfoListApi'] = json.dumps({'notarizationInfoList': notari_list.get('data')},
                                                   ensure_ascii=False)

    url = 'http://22.230.57.12:8080/housePropertyInfo/getHousePropertyInfo'
    house_info = request3(url, params, cookies)
    result['housePropertyInfoApi'] = json.dumps({'housePropertyInfo': house_info.get('data')}, ensure_ascii=False)

    return result


def save_house_info(data, cookies):
    url = "http://22.230.57.12:8080/guaranteeBaseInfo/saveGuaranteeManage"
    return request3(url, data, cookies)


def business_shangbao(driver):
    wait = WebDriverWait(driver, 100, poll_frequency=1)
    wait.until(
        EC.element_to_be_clickable((By.CSS_SELECTOR, """button[ng-click="saveContractInfos('saveBizInf')"]""")))
    # 等待保存成功后，点击全部保存，然后点击流程上报按钮
    driver.execute_script("window.scrollTo(0, 1000000)")
    confirm_button = driver.find_element_by_css_selector("""button[ng-click="saveContractInfos('saveBizInf')"]""")
    confirm_button.click()
    logger.info('3.0系统抵押登记证明填写任务 点击全部保存')
    time.sleep(3)

    # 流程上报
    shangbao = driver.find_element_by_css_selector("""button[ng-click="operationWorkFlow('nextTask')"]""")
    shangbao.click()

    time.sleep(3)

    dialogs = driver.find_elements_by_css_selector('.layui-layer.layui-layer-dialog')
    error = False
    error_dialog = None
    for dialog in dialogs:
        if '请先保存，方可上报' in dialog.text:
            error = True
            error_dialog = dialog
            break
    if error:
        error_dialog.find_element_by_css_selector('.layui-layer-btn0').click()
        time.sleep(1)
        business_shangbao(driver)

    if driver:
        driver.quit()
        driver = None
    logger.info('3.0系统抵押登记证明填写任务 流程上报')
    logger.info('流程上报结束')


def normal_shangbao(driver):
    wait = WebDriverWait(driver, 100, poll_frequency=1)
    wait.until(EC.element_to_be_clickable((By.ID, 'allSaveButton')))
    # 等待保存成功后，点击全部保存，然后点击流程上报按钮
    confirm_button = driver.find_element_by_id('allSaveButton')
    confirm_button.click()
    logger.info('3.0系统抵押登记证明填写任务 点击全部保存')
    time.sleep(3)
    # 流程上报
    shangbao = driver.find_element_by_css_selector("""button[ng-click="operationWorkFlow('nextTask')"]""")
    shangbao.click()
    logger.info('3.0系统抵押登记证明填写任务 流程上报')

    wait = WebDriverWait(driver, 50, poll_frequency=1)
    wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'div.layui-layer.layui-layer-dialog')))

    # 点击确认按钮
    dialog = driver.find_element_by_css_selector('div.layui-layer.layui-layer-dialog')
    alinks = dialog.find_elements_by_css_selector('a')
    for alink in alinks:
        if alink.text == '确定':
            alink.click()
            break

    time.sleep(3)

    wait = WebDriverWait(driver, 100, 2)
    wait.until(
        EC.presence_of_element_located((By.CSS_SELECTOR, 'div.layui-layer.layui-layer-page.layui-layer-rim')))

    dialog = driver.find_element_by_css_selector('div.layui-layer.layui-layer-page.layui-layer-rim')
    level1s = dialog.find_elements_by_css_selector('a.level1')
    if len(level1s) == 1:
        logger.info('找到流程节点： %s', level1s[0].text)
        level1s[0].click()
    elif len(level1s) > 1:
        # 查询流程信息：
        loans = driver.find_element_by_css_selector('#loanChangeId')
        trs = loans.find_elements_by_css_selector('tbody tr.ng-scope')
        # 去倒数第二行
        tr = trs[trs.__len__() - 2]
        user_name = tr.find_element_by_css_selector('td[ng-bind="item.userName"]').text
        for level in level1s:
            if level.text == user_name:
                logger.info('找到流程节点： %s', user_name)
                level.click()
                break
        pass
    else:
        logger.error('未找到流程节点, 流程上报失败')
        raise Exception(500, '未找到流程节点')

    # 点击确认按钮
    time.sleep(2)
    dialog.find_element_by_css_selector('a.layui-layer-btn0').click()
    logger.info('流程上报结束')
    time.sleep(3)

    # 浏览器退出
    if driver:
        driver.quit()


def get_package_info(business_key, cookies):
    url = 'http://22.230.57.12:8080/packageInfo/findPackageInfoByBusiId'
    params = {
        'busiPrKeyNo': business_key,
        'provCode': '3200',
        '_curMenuCode': None
    }
    return request3(url, params, cookies)


def get_package_no(busiPrKeyNo, taskId, contractType, cookies):
    """获取封包号"""
    url = 'http://22.230.57.12:8080/packageInfo/getPackageNo'
    params = {
        'contractType': contractType,
        'busiPrKeyNo': busiPrKeyNo,
        'taskId': taskId,
        '_curMenuCode': None,
    }
    return request3(url, params, cookies)


def get_qz_list_by_business_key(business_key, cookies):
    url = 'http://22.230.57.12:8080/warrantInfo/findWarrantInfoByBusiId'
    params = {
        'busiNo': business_key,
        'warrantStatusCode': '01',
        'provCode': '3200',
        '_curMenuCode': None
    }
    return request3(url, params, cookies)


def pack(data, cookies):
    """封包"""
    url = 'http://22.230.57.12:8080/warrantManagement/warrantInputApply'
    """
    obj.busiType = "1";										//业务类型 1,入库2，出库3，借出，4，归还
    obj.busiPrKeyNo = $scope.warrantInput.busiNo;			//业务编号
    obj.packageInfoList = packageInfoListArr;				//未封包数据

    obj.custId = $scope.warrantInput.custId;//客户id 
    //暂时如此解决================随后工作流扩展字段迁过来后再删除yjh注释
    if("03" == extensionFieldOne.approveType&&$scope.warrantInput.custNo==undefined){
        var custCtrl;
        custCtrl=getScopeByName($scope,"客户信息");
        if(custCtrl==undefined){
            custCtrl=getScopeByName($scope,"借款人信息");	
        }
        if(custCtrl!=undefined){
         $scope.warrantInput.custNo	= custCtrl.borrowerInfo.custNo; 
         $scope.warrantInput.custName = custCtrl.borrowerInfo.custName;
        }
    }
    //暂时如此解决================随后工作流扩展字段迁过来后再删除yjh注释
    obj.custNo = $scope.warrantInput.custNo; 				//借款人编号----车房null
    obj.custName = $scope.warrantInput.custName; 			//借款人名称

    obj.contractNo = $scope.warrantInput.contractNo;		//合同号
    // obj.contractType = "01";								//合同类型
    obj.contractType =  $scope.warrantInput.contractType;	//合同类型
    obj.contractTerm = $scope.warrantInput.contractTerm;	//合同期限----车房null

    obj.loanCode = $scope.warrantInput.loanCode;			//贷种 
    obj.outIndbNo = $scope.warrantInput.outIndbNo; 			//入库编号-获取的封包编号
    obj.busiSendDate = $scope.warrantInput.busiSendDate; 	//出入库申请日期
    """
    return request3(url, data, cookies)


def package(business, cookie_dict):
    """封包全过程"""
    # 权证新增完成后， 查询所有的不动产权证
    # 根据抵押物查询抵押登记证明
    # 获取当前申请中所有的证明
    res = get_qz_list_by_business_key(business.get('businessKey'), cookie_dict)
    qz_list = res.get('data').get('list')
    package_qz_list = []
    for qz in qz_list:
        # 过滤抵押登记证明
        if qz.get('ownershipVchrTypeCode') == '40':
            package_qz_list.append(qz)

    if len(package_qz_list) < 1:
        logger.warning('%s 封包结束， 未找到抵押登记证明', business.get('customName'))
        return

    base_flow_name = business.get('baseWorkFlowName')
    if '个人一手' in base_flow_name or '个人二手' in base_flow_name:
        main_contract = NormalLoan(business, cookie_dict).get_contract_list()[0]
        main_contract['contractType'] = '02'
        main_contract['limitDurTerm'] = main_contract.get('contractTerm')
    else:
        main_contract = find_main_contract(business.get('businessKey'), cookie_dict)
    if main_contract is None:
        logger.error('%s 封包失败， 合同未找到', business.get('customName'))
        return

    # 获取当前申请下所有的封包详情
    package_info = get_package_info(business.get('businessKey'), cookie_dict).get('data')

    business_extend_info = json.loads(business.get('extensionFieldOne'))

    for qz in package_qz_list:
        need_continue = False
        # 检查当前权证信息是否已经封包了。
        for item in package_info:
            warrantInfoList = item.get('warrantInfoList')  # 押品信息
            for warrant in warrantInfoList:
                # 当前权证已经封包了。
                if warrant.get('collatId') == qz.get('warrantTabPrKey') and \
                        warrant.get('ownershipVchrTypeCode') == '40':
                    need_continue = True
                    break

        if need_continue:
            continue

        packageInfo = {
            'packageState': '01',
            'ownerNames': [],
            'warrantTabPrKeys': [],
            'phyDocTypes': [],  # 权证类型
            'phyDocNos': [],  # 权证编号
        }

        # 获取封包号，然后封包
        res = get_package_no(
            business.get('businessKey'),
            business.get('taskId'),
            main_contract.get('contractType'),
            cookie_dict
        )
        no = res.get('data').get('packetNo')
        loan_code = res.get('data').get('loanCode')
        packageInfo['packetNo'] = no

        if qz.get('comRghtPersNames') is not None and \
                qz.get('comRghtPersNames') not in packageInfo.get('ownerNames'):
            packageInfo.get('ownerNames').append(qz.get('comRghtPersNames'))
        packageInfo.get('phyDocTypes').append(qz.get('phyDocType'))
        packageInfo.get('warrantTabPrKeys').append(
            qz.get('warrantTabPrKey') + ':' + qz.get('warrantInsuNotrztFlag') + ':' + qz.get('provCode')
        )
        packageInfo.get('phyDocNos').append(qz.get('phyDocNo'))

        packageInfo['ownerNames'] = ",".join(packageInfo.get('ownerNames'))
        packageInfo['phyDocTypes'] = ",".join(packageInfo.get('phyDocTypes'))
        packageInfo['warrantTabPrKeys'] = ",".join(packageInfo.get('warrantTabPrKeys'))
        packageInfo['phyDocNos'] = ",".join(packageInfo.get('phyDocNos'))

        obj = {
            'busiType': '1',
            'busiPrKeyNo': business.get('businessKey'),
            'packageInfoList': [packageInfo],
            'custNo': business_extend_info.get('custNo'),
            'custId': business_extend_info.get('custId'),
            'custName': business.get('customName'),
            'contractNo': main_contract.get('contractNo'),
            'contractType': main_contract.get('contractType'),
            'contractTerm': main_contract.get('limitDurTerm'),
            'loanCode': loan_code,
            'outIndbNo': 'R320246912021012326',  # 针对每一个分行是指定的
            'busiSendDate': datetime.now().strftime('%Y-%m-%d')
        }

        data = {
            'data': json.dumps(obj, ensure_ascii=False),
            'provCode': '3200',  # 江苏省
            'taskId': business.get('taskId'),
        }

        # 封包
        pack(data, cookie_dict)
        logger.info('%s 权证已封包', qz.get('phyDocNo'))
    logger.info('封包完成')


class YzyhRequest(object):
    cookie_dict = {}
    plugin_path = path.abspath(path.join(execute_path, '../..'))

    @classmethod
    def login(cls):
        data = {
            'loginType': None,
            'loginUriSuffix': None,
            'username': USERNAME,
            'password': PASSWORD,
        }
        m = MultipartEncoder(data)
        headers = get_headers(m.content_type)
        response = requests.post(YZYH_REQUEST_URL.get('LOGIN_URL'), data=m, headers=headers)
        cookie: str = response.request.headers.get('Cookie')
        for cookie_part in cookie.split(";"):
            [key, value] = cookie_part.split('=')
            YzyhRequest.cookie_dict[key] = value
        return YzyhRequest.cookie_dict

    @classmethod
    def get_task_list(cls, page: int = 1, params=None):
        if params is None:
            params = {}
        data = {
            'wfClassifyCode': 'root068',
            'taskPoolStatus': '1',
            'state': '1',
            'taskExpandData': json.dumps(params, ensure_ascii=False),
            'pageNum': str(page),
            'pageSize': '10000',
        }
        m = MultipartEncoder(data)
        headers = get_headers(m.content_type)
        response = requests.post(YZYH_REQUEST_URL.get('TASK_LIST_URL'), data=m, headers=headers,
                                 cookies=YzyhRequest.cookie_dict)
        return parse_response(response)

    @classmethod
    def open_card(cls, driver, text: str):
        """打开待办页签"""
        logger.info('3.0系统抵押登记证明填写任务 打开待办列表')
        wait = WebDriverWait(driver, 100, poll_frequency=2)
        wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'font.ziti.ng-binding')))
        wait = WebDriverWait(driver, 100, poll_frequency=2)

        def w(_driver):
            items = driver.find_elements_by_css_selector('font.ziti.ng-binding')
            for item in items:
                if item.text == text:
                    return True
            return False

        wait.until(w)

        fonts = driver.find_elements_by_css_selector('font.ziti.ng-binding')
        for font in fonts:
            if font.text == text:
                font.click()
                time.sleep(5)
                return

    def login_system(self, driver):
        if not self.cookie_dict:
            self.login()
        index = "http://22.230.57.12:8080/login"
        driver.get(index)
        logger.info('3.0系统抵押登记证明填写任务 打开浏览器')
        wait = WebDriverWait(driver, 100, poll_frequency=2)
        wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.login_title')))

        driver.delete_all_cookies()
        for key in YzyhRequest.cookie_dict:
            driver.add_cookie({
                'name': key,
                'value': YzyhRequest.cookie_dict.get(key)
            })
        logger.info('3.0系统抵押登记证明填写任务 登录成功')
        time.sleep(3)
        index_url = "http://22.230.57.12:8080/index/#/index"
        driver.get(index_url)

    def goto_detail(self, contract_id):
        """打开对应客户的详细编辑界面"""
        driver = CreateDriver.create('chrome')
        self.login_system(driver)

        self.open_card(driver, '待办/已办任务列表')

        from apps.app import app
        with app.app_context():
            info: BankSideInfo = BankSideInfo.get(contract_id)
            logger.info('3.0系统抵押登记证明填写任务开始， 客户名称： %s, 业务类型： %s', info.custom_name, info.baseWork_flow_name)

        wait = WebDriverWait(driver, 300, poll_frequency=5)
        wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'button[ng-click="matching(1);listSearch(1)"]')))
        # 加载完后点击查询
        input_ele = driver.find_element_by_css_selector('input[ng-model="businessTaskExpandData.customName"]')
        if input_ele.is_displayed():
            input_ele.send_keys(info.custom_name)

        # 点击查询
        button = driver.find_element_by_css_selector('button[ng-click="matching(1);listSearch(1)"]')
        if button.is_enabled():
            button.click()
        logger.info('3.0系统抵押登记证明填写任务 执行查询')

        wait = WebDriverWait(driver, 100)
        wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'a[ng-click="process(item.formKey,item)"]')))

        wait = WebDriverWait(driver, 100)
        wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, 'td[ng-bind="item.customName"]')))

        # 找到当前客户数据，并点击业务处理按钮
        trs = driver.find_elements_by_css_selector('tr[ng-click="checked(item)"]')
        for tr in trs:
            if tr is not None and tr.is_displayed():
                td = tr.find_element_by_css_selector('td[ng-bind="item.customName"]')
                if td.is_displayed() and td.text == info.custom_name:
                    alink = tr.find_element_by_css_selector('a[ng-click="process(item.formKey,item)"]')
                    if alink.is_enabled() and alink.text == '业务处理':
                        alink.click()
                        break
        logger.info('3.0系统抵押登记证明填写任务 进入详情界面')
        # 完成详情界面打开
        return driver

    def process_house_datas(self, contract_ids, confrimed_ids):
        if not self.cookie_dict:
            self.login()
        for contract_id in contract_ids:
            try:
                """抽取不动产数据填写银行系统"""
                self.process_house_data(contract_id)
                from apps.app import app
                with app.app_context():
                    # 当前单据如果为一手房，填报完成抵押登记证明后将状态修改为已确认，如果不是就将状态修改为已完成
                    info: BankSideInfo = BankSideInfo.get(contract_id)
                    if '个人一手' in info.baseWork_flow_name:
                        info.state = 'confirmed'
                    else:
                        info.state = 'completed'
                    info.save(commit=True)
                    logger.info('3.0系统抵押登记证明填写任务完成， 客户名称： %s, 业务类型： %s', info.custom_name, info.baseWork_flow_name)
            except Exception as e:
                logger.error('3.0系统抵押登记证明填写失败， 客户名称： %s， 错误： %s', contract_id, traceback.format_exc())
                from apps.app import app
                with app.app_context():
                    info = BankSideInfo.get(contract_id)
                    info.state = 'approved'
                    info.save(commit=True)
        for contract_id in confrimed_ids:
            try:
                """抽取不动产数据填写银行系统的押品管理模块"""
                self.process_yapin_data(contract_id)
                from apps.app import app
                with app.app_context():
                    # 当前单据为一手房，填报押品管理将状态修改为已完成，如果失败状态退回到已确认
                    info: BankSideInfo = BankSideInfo.get(contract_id)
                    info.state = 'completed'
                    info.save(commit=True)
                    logger.info('3.0系统押品管理填写任务完成， 客户名称： %s, 业务类型： %s', info.custom_name, info.baseWork_flow_name)
            except Exception as e:
                logger.error('3.0系统押品管理证明填写失败， 客户名称： %s， 错误： %s', contract_id, traceback.format_exc())
                from apps.app import app
                with app.app_context():
                    info = BankSideInfo.get(contract_id)
                    if info.state != 'error':
                        info.state = 'confirmed'
                        info.save(commit=True)

    def process_house_data(self, contract_id):
        """抽取不动产系统数据， 回填抵押登记证明 或 预告抵押登记证明"""
        # 验证cookie是否有效
        if self.cookie_dict:
            res = requests.get('http://22.230.57.12:8080/nodedispatcher/compute/getbyuser?user=20081522990',
                               cookies=self.cookie_dict)
            try:
                parse_response(res)
            except Exception as e:
                if e.args[0] == '403':
                    self.cookie_dict.clear()
                    logger.error('抵押登记证明填报任务, 回话失效')
                raise

        from apps.app import app
        with app.app_context():
            info: BankSideInfo = BankSideInfo.get(contract_id)
            res = self.get_task_list(params={'customName': info.custom_name})

            extend_list: List[BankSideExtendInfo] = BankSideExtendInfo.filter_by(contract_id=contract_id).all()

        business = None
        if get_value(res, 'data.grid') is not None:
            total = get_value(res, 'data.grid.total')
            if total < 1:
                raise Exception(500, '待办中没有找到 %s 的单据', info.custom_name)
            data = get_value(res, 'data.grid.list')
            for item in data:
                if item.get('businessKey') == info.business_key:
                    business = item
        if business is None:
            return

        # 上传抵押登记证明附件
        self.upload_file(info.id)

        base_flow_name = business.get('baseWorkFlowName')
        # 获取当前申请下的所有抵押物列表 collat_list
        if base_flow_name in ['个人二手商业用房贷款', '个人二手房贷款', '个人一手房贷款', '个人一手商业用房贷款']:
            flow_type = 'normal'
            collat_list = NormalLoan(business, self.cookie_dict).get_colla_list()
        else:
            flow_type = 'business'
            collat_list = Shangdaitong(business, self.cookie_dict).get_colla_list()

        need_fengbao = True

        # 新增抵押物的抵押登记证明
        for collat in collat_list:
            extend = [e for e in extend_list if e.collat_id == collat.get('collatId')][0]
            with app.app_context():
                approve: HouseApprove = HouseApprove.filter_by(extend_id=extend.id).first()

            params = {
                'collatKindCode': collat.get('collatKindCode'),  # 押品类型
                'collatNo': collat.get('collatNo'),  # 押品编号
                'collatId': collat.get('collatId'),  # 押品id
                'phyDocNo': approve.qz_no,  # 权证编号
                'enrollAmt': approve.dj_amt,  # 登记金额
                'enrollDate': approve.dj_start_date,  # 开始时间
                'enrollDateExistStageFlag': '1',  # 是否存在到期日
                'enrollEndDate': approve.dj_end_date,  # 到日期
                'warrantCateg': '02',  # 纸质权证
                'ownershipVchrTypeCode': '40',  # 权证类型 40: 抵押登记证明 42: 预告抵押登记证明
            }
            if approve.qz_type == '预告抵押登记证明':
                need_fengbao = False
                params['warrantCateg'] = '01'
                params['ownershipVchrTypeCode'] = '42'  # 预告抵押登记证明

            # 新增抵押登记证明
            add_qz(params, business.get('taskId'), self.cookie_dict)

        # 封包  # 一手房不需要封包，因为是电子凭证
        if need_fengbao:
            package(business, self.cookie_dict)

        # 全部保存，提交流程
        driver = None
        try:
            driver = self.goto_detail(contract_id)
        except:
            driver.quit()
            raise

        time.sleep(3)

        if flow_type == 'normal':
            # 预告抵押登记
            normal_shangbao(driver)
        else:
            # 正式抵押登记
            business_shangbao(driver)

        # 流程结束后将单据状态修改为已确认 或 完成
        with app.app_context():
            info = BankSideInfo.get(contract_id)
            if flow_type == 'normal':
                info.state = 'confirmed'
            else:
                info.state = 'completed'
            info.save(commit=True)

    @classmethod
    def upload_file(cls, contract_id):
        """根据单据id查找产权证附件"""
        # 将文件复制到插件对应的目录下面。
        # 目录规则： 文件夹： 当前日期_时分秒_1
        # 文件名规则： 就是原始文件的文件名
        logger.info('3.0系统抵押登记证明填写任务 上传担保交易材料')
        from apps.app import app
        with app.app_context():
            info: BankSideInfo = BankSideInfo.get(contract_id)
            extend_list = BankSideExtendInfo.filter_by(contract_id=contract_id).all()
            extend_ids = [e.id for e in extend_list]
            approve_list: List[HouseApprove] = HouseApprove.filter(HouseApprove.extend_id.in_(extend_ids)).all()
        dir_name = datetime.now().strftime('%Y%m%d_%H%M%S_1')
        dir_path = path.abspath(path.join(cls.plugin_path, './tmp', dir_name))
        if not path.exists(dir_path):
            os.mkdir(dir_path)
        if approve_list is None:
            raise Exception(500, '未找到产权证书')
        # 上传多个文件
        for approve in approve_list:
            logger.info('开始上传文件 客户名称： %s, 文件名称: %s', info.custom_name, approve.file)
            origin_path = path.join(file_basepath, approve.file)
            target = path.join(dir_path, approve.file)
            copyfile(origin_path, target)

            filename = approve.file
            filename_0 = filename.split('.')[0] + '_0.pdf'

            def get_timestamp():
                return datetime.now().strftime('%Y%m%d%H%M%S')

            headers = {
                'Content-Type': 'application/x-www-form-urlencoded; charset=UTF-8',
                'Referer': 'http://21.154.3.226:58610/99710670000/upload.html?random={random}'.format(
                    random=get_timestamp()),
                'Origin': 'http://21.154.3.226:58610',
                'Sec-Fetch-Dest': 'empty',
                'Sec-Fetch-Mode': 'cors',
                'Sec-Fetch-Site': 'same-origin',
            }

            params = {"opetype": "CF1"}
            requests.post('http://127.0.0.1:58610/local', data=params, headers=headers)

            params = {
                "opetype": "CF8",
                "change": [
                    {
                        "orginalName": "/tmp/{dirname}/{filename}".format(dirname=dir_name, filename=filename),
                        "toName": "/tmp/{dirname}/担保物资料_{filename}".format(dirname=dir_name, filename=filename_0)
                    }
                ]
            }
            # 修改文件名称
            requests.post(
                'http://127.0.0.1:58610/local',
                headers=headers,
                data=json.dumps(params, ensure_ascii=False).encode('utf-8'),
                allow_redirects=False
            )

            now = get_timestamp()
            prefix = info.business_key + '_' + now
            s = 0
            for i in prefix:
                s += ord(i)
            s %= 100
            zip_name = "99710670000_{businessKey}_{time}.zip".format(
                businessKey=info.business_key,
                time=now + str(s).rjust(2, '0')
            )

            params = {
                "opetype": "UP1",
                "request": {
                    "fileName": zip_name,
                    "fileSize": "163499"
                },
                "files": ["/tmp/{dirname}/担保物资料_{filename}".format(dirname=dir_name, filename=filename_0)],
                "msgfile": {
                    "busi": {
                        "busiNo": info.business_key,
                        "batchId": info.business_key,
                        "busiType": "03",
                        "approveStatus": "73",
                        "fileType": ["CFB0030001"]
                    },
                    "files": ["担保物资料_{filename}".format(filename=filename_0)],
                    "sysHead": {
                        "opeSys": "99710670000",
                        "opeType": "T01101",
                        "opeUser": "20081522990",
                        "opeOrg": "32024691",
                        "opeTime": get_timestamp(),
                    },
                    "zipName": zip_name
                }
            }
            res = requests.post(
                'http://127.0.0.1:58610/99710670000',
                headers=headers,
                data=json.dumps(params, ensure_ascii=False).encode('utf-8')
            )
            res = parse_response(res)
            if res.get('result') != 0:
                raise Exception(500, '上传文件失败！ ex: ' + res.get('desc'))
            logger.info('文件上传成功 客户名称： %s, 结束时间： %s', info.custom_name, curtime())

    def process_yapin_data(self, contract_id):
        """处理押品数据"""
        """一手房押品管理回填, 肯定只有一个押品"""
        # 根据押品id， 获取权证信息
        # 直接写入权证信息
        from apps.app import app
        with app.app_context():
            info: BankSideInfo = BankSideInfo.get(contract_id)
            extend_list: List[BankSideExtendInfo] = BankSideExtendInfo.filter_by(contract_id=contract_id).all()
            logger.info('3.0系统押品管理填写任务开始， 客户名称： %s, 业务类型： %s', info.custom_name, info.baseWork_flow_name)

        """
        collatKindCode: "C010101"
        createTime: 946656000000
        phyDocName: "抵押登记证明"
        phyDocType: "40"
        sysUniqueNo: "114"
        updTime: 946656000000
        """

        for extend in extend_list:
            # 获取押品权证信息 # 判断当前押品中是否已经存在抵押登记证明。存在就不再新增权证信息
            res = get_house_qz(extend.collat_id, self.cookie_dict)
            if get_value(res, 'data') is not None:
                data = get_value(res, 'data')
                for item in data:
                    if item.get('ownershipVchrTypeCode') == '40':
                        if item.get('phyDocNo') != '' or item.get('phyDocNo') is None:
                            logger.info('押品 %s 已经存在抵押登记证明', extend.collat_id)
                            continue
            # 没有内容就补充内容
            # 获取基本信息
            from apps.app import app
            with app.app_context():
                confirm: HouseConfirm = HouseConfirm.filter_by(extend_id=extend.id).first()
                new_item = {
                    "warrantStatusCode": "01",
                    "statusName": "未入库",
                    "validBeginDate": confirm.dj_start_date,
                    "validEndDate": confirm.dj_end_date,
                    "ownershipVchrTypeCode": "40",
                    "phyDocNo": confirm.qz_no,
                    "mrtgEnrollInstType": "02",  # 房屋管理部门
                    "enrollInstName": "盐城市自然资源和规划局",
                    "enrollAmt": confirm.dj_amt,
                    "enrollDate": confirm.dj_start_date,
                    "enrollDateExistStageFlag": "1",
                    "enrollEndDate": confirm.dj_end_date
                }
            data = get_house_info(extend.collat_id, self.cookie_dict)

            warrant_list: List = get_value(res, 'data')
            warrant_list.append(new_item)
            data['warrantInfoListApi'] = json.dumps({'warrantInfoList': warrant_list}, ensure_ascii=False)

            # 调用接口保存
            res = save_house_info(data, self.cookie_dict)

            if res is None or res.get('status') != '200':
                logger.error('%s 正式抵押登记证明新增失败！', info.custom_name)
                with app.app_context():
                    info.state = 'waitCompleted'
                    info.save(commit=True)
                return
            info.state = 'completed'
            info.save(commit=True)

        # 填报完成后，权证入库
        business = get_business_item(info.business_key, self.cookie_dict)
        # 获取封包信息。 如果已经存在封包，就不再封包
        # 封包
        package(business, self.cookie_dict)
        # 完成封包

    """
    查询权证信息
    通过接口新增权证信息
    点击全部保存，点击流程上传。
    
    押品管理
    """
